package com.hx.localmiaosha.service.imp;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.hx.common.api.MiaoshaGoodsService;
import com.hx.common.api.OrderService;
import com.hx.common.common.SnowflakeIdWorker;
import com.hx.common.common.enums.ResultStatus;
import com.hx.common.constant.GoodServerConstant;
import com.hx.common.domain.MiaoshaUser;
import com.hx.common.exception.GlobleException;
import com.hx.common.to.OrderMessageTo;
import com.hx.common.to.RedisGoodsTo;
import com.hx.localmiaosha.interceptor.AuthInterceptor;
import com.hx.localmiaosha.service.MiaoShaService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @Author wonghiu
 * @Date 2021/6/5 12:59
 * @Version 1.0.1
 */
@Service("miaoShaService")
@Slf4j
public class MiaoShaServiceImp implements MiaoShaService {
    private static Logger logger = LoggerFactory.getLogger(MiaoShaServiceImp.class);
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Reference(check = false)
    private MiaoshaGoodsService miaoshaGoodsService;
    @Reference(check = false)
    private OrderService orderService;

    @Override
    public boolean checkVerifyCode(MiaoshaUser user, long goodsId, int verifyCode) {
        return false;
    }

    @Override
    public String createMiaoshaPath(MiaoshaUser user, long goodsId) {
        return null;
    }

    @Override
    public boolean checkPath(MiaoshaUser user, long goodsId, String path) {
        return false;
    }

    @Override
    public Long getMiaoshaResult(Long valueOf, long goodsId) {
        return null;
    }

    @Override
    public Long kill(Long goodsId, String randomCode) {
        // ThreadLocal要在方法内获取
        // 获取用户信息
        MiaoshaUser loginUserVo = AuthInterceptor.loginUser.get();
        // 获取商品信息
        String json = redisTemplate.opsForValue().get(GoodServerConstant.GOODS_INFO_PREFIX + goodsId);
        if (StringUtils.isEmpty(json)) {
            return null;
        } else {
            RedisGoodsTo goodsTo = JSON.parseObject(json, RedisGoodsTo.class);
            // 校验合法性
            long startDte = goodsTo.getStartDate().getTime();
            long endDate = goodsTo.getEndDate().getTime();
            long nowDate = new Date().getTime();

            long ttl = endDate - nowDate;
            // 校验时间
            if (nowDate >= startDte && nowDate <= endDate) {
                // 校验随机码和商品id
                String goodRandomCode = goodsTo.getRandomCode();
                Long id = goodsTo.getGoodsId();
                if (goodRandomCode.equals(randomCode) && id.equals(goodsId)) {
                    // TODO 验证购买数量不超过限制
                    // 验证是否已经买过，只要秒杀成功就去占位。 userId_skuId
                    String redisKey = GoodServerConstant.GOODS_USER + loginUserVo.getId() + "_" + goodsId;

//                    Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(redisKey,"1",ttl, TimeUnit.MILLISECONDS);
                    Boolean aBoolean = true;
                    if (aBoolean != null) {
                        //占位成功说明从来没有买过,通过信号量锁库存
                        RSemaphore semaphore = redissonClient.getSemaphore(GoodServerConstant.GOODS_STOCK_PREFIX + goodsId);
                        try {
                            // 目前每个人只允许抢一件
                            if (semaphore.tryAcquire(1, 100, TimeUnit.MILLISECONDS)) {
                                //秒杀成功
                                //TODO 快速下单。发送MQ消息
                                //获取分布式唯一订单号
                                long orderId = SnowflakeIdWorker.getOrderId(1, 1);
                                OrderMessageTo orderMessageTo = new OrderMessageTo();
                                orderMessageTo.setGoodsId(goodsId);
                                orderMessageTo.setOrderId(orderId);
                                orderMessageTo.setCountGoods(1);
                                orderMessageTo.setUserId(loginUserVo.getId());
                                // 发送成功就算订单提交成功
                                rabbitTemplate.convertAndSend("order-event-exchange", "order.miaosha.order", orderMessageTo);
                                return orderId;
                            }
                        } catch (Exception e) {
                            throw new GlobleException(ResultStatus.MIAOSHA_FAIL);
                        }
                    } else {
                        throw new GlobleException(ResultStatus.REPEATE_MIAOSHA);
                    }
                } else {
                    logger.info("随机码不匹配");
                    throw new GlobleException(ResultStatus.MIAOSHA_RANDOMCODE_FAIL);
                }

            }
        }

        throw new GlobleException(ResultStatus.MIAOSHA_GETGOODINFO_FAIL);
    }
}

